﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using KPIS.GERP.Models;
using KPIS.GERP.Models.Class;
using KPIS.GERP.Models.SYS;
using KPIS.GERP.WEB.GIMS.UserService;
using System.IO;
using System.Reflection;
using System.Data.Entity;

namespace KPIS.GERP.WEB.GIMS.Class
{
    public static class GimsMembership
    {
        private const string CookieName = "UserDetail";
        public static DateTime NextExpire = DateTime.Now.AddHours(8760);
        private static User[] _UserCache;

        public static void Login(int userId)
        {
            CookieSet("UserSeq", userId.ToString());
            HttpContext.Current.Session["User"] = null;
            HttpContext.Current.Session["UserFilteredMenus"] = null;
        }
        public static int CurrentUserId
        {
            get
            {
                return User == null ? 0 : User.UserId;
            }
        }

        public static int CurrentEmpId
        {
            get
            {
                return User == null || User.Employee == null ? 0 : User.Employee.EmpId;

            }
        }

        public static string CurrentEmpCitizen
        {
            get
            {
                return User == null || User.Employee == null ? "" : User.Employee.Citizen;
            }
        }

        public static int CookieUserId
        {
            get
            {
                int userSeq = ConvertUtility.ConvertOrDefaultStringToInt(CookieGet("UserSeq"));
                return userSeq;
            }
        }

        public static string CurrentUserName
        {
            get
            {
                return User==null ? "": User.Code;
            }
        }

        public static string CurrentUserRoles()
        {
            int currentUserId = CurrentUserId;
            var data = new GERPContext().UserRoles.Include(o => o.Role)
                .Where(
                    o =>
                        o.UserId == currentUserId &&
                        o.Role != null &&
                        o.RecordStatus != "D" &&
                        o.Role.RecordStatus != "D" &&
                        o.Role.System == "WEBGIMS")
                //  .Select(o => "- " + o.Role.RoleName + " - " + o.Role.Remarks)
                .GroupBy(o => o.RoleId)
                .Select(o => o.FirstOrDefault().Role)
                .Select(o => "- " + o.RoleName + " - " + o.Remarks);
            return string.Join("<br/>", data.ToArray());
        }

        public static Models.HRM.Employee Employee
        {
            get
            {
                return User==null ? null: User.Employee;
            }
        }
         
        public static bool IsCurrentUserAdmin
        {
            get { return User != null && User.IsAdmin; }
        }

        public static bool IsLogin
        {
            get
            { 
                return CookieUserId != 0;
            }
        }

        public static User[] UsersList
        {
            get
            {
                if (_UserCache != null && _UserCache.Any()) return _UserCache;

                try
                {
                    using (var userService = new UserServiceClient())
                    {
                        _UserCache = userService.GetUsers();
                    }
                }
                catch (ReflectionTypeLoadException ex)
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (Exception exSub in ex.LoaderExceptions)
                    {
                        sb.AppendLine(exSub.Message);
                        if (exSub is FileNotFoundException)
                        {
                            FileNotFoundException exFileNotFound = exSub as FileNotFoundException;
                            if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
                            {
                                sb.AppendLine("Fusion Log:");
                                sb.AppendLine(exFileNotFound.FusionLog);
                            }
                        }
                        sb.AppendLine();
                    }
                    string errorMessage = sb.ToString();
                    throw new Exception("Reflection as following:, " + errorMessage + ",. " + ex.Message);
                    //Display or log the error based on your application.
                }
                catch (Exception ex)
                {
                    throw new Exception("Other Exception,. " + ex.Message, innerException: ex);
                }

                return _UserCache;
            }
        }

        public static List<User> GetUsers()
        {
            return UsersList.ToList();
        }
          
        public static void AuditLogin(int userId)
        {
            CookieSet("UserSeq", "" + userId);
        }
         
        public static void AuditLogout()
        {
            // CookieSet("user_seq", "");
        }


        #region Base

        private static string ConvertString(object o)
        {
            return o == null ? null : Convert.ToString(o);
        }
        private static void SessionSet(string key, string value)
        {
            HttpContext.Current.Session[key] = value;
        }

        private static string SessionGet(string key)
        {
            return ConvertString(HttpContext.Current.Session[key]);
        }

        private static void CookieSet(string key, string value)
        {
            HttpCookie cookie = new HttpCookie(CookieName);
            cookie[key] = value;
            cookie.Expires = NextExpire; 
            HttpContext.Current.Response.SetCookie(cookie);
        }

        private static string CookieGet(string key)
        {
            var cookie = HttpContext.Current.Request.Cookies[CookieName] ?? HttpContext.Current.Response.Cookies[key];
            if (cookie == null) return "";
            cookie.Expires = NextExpire;
            return cookie[key];
        }

        public new static string ToString()
        {
            StringBuilder result = new StringBuilder();
            result.Append("This is session<br>");
            foreach (var s in HttpContext.Current.Session.Keys)
            {
                result.Append(s);
                result.Append("=");
                result.Append(HttpContext.Current.Session[s.ToString()]);
                result.Append("<br>");
            }
            result.Append("<br>");
            result.Append("This is cookie<br>");
            HttpCookie ck = HttpContext.Current.Request.Cookies[CookieName];
            if (ck != null && ck.HasKeys)
            {
                foreach (var s in ck.Values)
                {
                    if (s != null)
                    {
                        result.Append(s);
                        result.Append("=");
                        result.Append(ck[s.ToString()]);
                        result.Append("<br>");
                    }
                }
            }
            return result.ToString();
        }

        public static void Logout()
        { 

        }

        #endregion
        
        // base property
        public static User User
        {
            get
            {
                if (HttpContext.Current.Session["User"] as User != null)
                {
                    return (User) HttpContext.Current.Session["User"];
                }

                HttpContext.Current.Session["User"] = UsersList.FirstOrDefault(o => o.UserId == CookieUserId);
                return (User)HttpContext.Current.Session["User"];
            }
        }

    }
}